import os
import re
import json
import subprocess

from pathlib import Path

from ollama import Client

def md2latex(filepath):
    """将markdown文档转换为latex文件

    Args:
        filepath (_type_): _description_
    """
    status = False
    try:
        folder = os.path.dirname(filepath)
        path_obj = Path(filepath)
        subprocess.run(
            ["pandoc", filepath, "-o", f"{folder}/{path_obj.stem}.tex"],
            capture_output=True,
            text=True,
            check=True
        )
        status = True

    except Exception as e:
        status = False
    finally:
        return status
    

def ask_local_llm(messages, model: str = "qwen3:14b"):
    try:
        res_str = None
        client = Client(host="http://host.docker.internal:11434")
        response = client.chat(model=model, messages=messages)
        content = response['message']['content']
        if "</think>" in content:
            res_str = content.split("</think>")[-1].strip()
        else:
            res_str = content
    except Exception as e:
        print(e)
    finally:
        return res_str


def load_json(file_path):
    if not os.path.exists(file_path):
        raise FileNotFoundError(f"The file {file_path} does not exist.")

    with open(file_path, "r", encoding="utf-8", errors="ignore") as file:
        data = json.load(file)

    return data


def run_pdflatex(tex_file_path, timeout=30):
    """
    调用 pdflatex 编译单个 tex 文件,生成 PDF
    """
    try:
        path_obj = Path(tex_file_path)
        subprocess.run(
            ["pdflatex", "-interaction=nonstopmode", path_obj.stem],
            check=True,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            cwd=path_obj.parent
        )
        return True
    except Exception as e:
        return False



def sanitize_latex(text):
    """
    增强版 LaTeX 兜底函数：
    - 自动闭合未闭合环境（支持嵌套）
    - 智能转义特殊符号（% _ &，公式内不转义 &）
    - 替换 Unicode 数学符号为 LaTeX
    - 自动将裸露数学表达式补进 $...$
    - 处理特殊空格和不可见字符
    - 额外转义未知 LaTeX 控制序列，避免 Undefined control sequence 错误
    """

    # -----------------------------
    # 1 处理环境闭合，使用堆栈跟踪嵌套
    # -----------------------------
    env_stack = []
    pattern_begin = re.compile(r"\\begin\{(\w+)\}")
    pattern_end = re.compile(r"\\end\{(\w+)\}")

    lines = text.split("\n")
    for line in lines:
        # 检查 begin
        for m in pattern_begin.finditer(line):
            env_stack.append(m.group(1))
        # 检查 end
        for m in pattern_end.finditer(line):
            if m.group(1) in env_stack:
                env_stack.remove(m.group(1))

    # 自动闭合未闭合环境
    for env in reversed(env_stack):
        lines.append(f"\\end{{{env}}}")

    text = "\n".join(lines)

    # -----------------------------
    # 2 转义特殊符号 % _，除了已转义的
    # -----------------------------
    text = re.sub(r"(?<!\\)%", r"\\%", text)
    text = re.sub(r"(?<!\\)_", r"\\_", text)

    # -----------------------------
    # 3 智能处理 &
    # -----------------------------
    def replace_ampersand(match):
        start = match.start()
        before = text[:start]
        in_env = False
        for env in ["align", "tabular", "matrix"]:
            if before.count(f"\\begin{{{env}}}") > before.count(f"\\end{{{env}}}"):
                in_env = True
                break
        return "&" if in_env else "\\&"

    text = re.sub(r"(?<!\\)&", replace_ampersand, text)

    # -----------------------------
    # 4 替换 Unicode 空格和不可见字符
    # -----------------------------
    # text = re.sub(r"[\u202F\u200B\u00A0\u2009]", " ", text)
    text = re.sub(r"[\u2000-\u200B\u202F\u00A0]", " ", text)

    # -----------------------------
    # 5 替换数学符号
    # -----------------------------
    symbol_map = {
        "β": r"$\beta$", "α": r"$\alpha$", "γ": r"$\gamma$",
        "≥": r"$\geq$", "≤": r"$\leq$", "±": r"$\pm$",
        "°": r"$^\circ$", "×": r"$\times$", "∞": r"$\infty$",
        "⁻": r"$^{-}$",  # 避免 U+207B 造成 undefined control sequence
        "⁺": r"$^{+}$",  # 额外常见上标
    }

    for uni, latex_sym in symbol_map.items():
        text = text.replace(uni, latex_sym)

    # -----------------------------
    # 6 自动把裸数学表达式补进公式模式
    # -----------------------------
    text = re.sub(r"(?<!\$)(\d+\s*[<>=]\s*\d+)(?!\$)", r"$\1$", text)

    # -----------------------------
    # 7 转义潜在未知控制序列
    # -----------------------------
    text = re.sub(r"\\([A-Za-z]+)(?![A-Za-z*])", r"\\textbackslash{\1}", text)
    
    
    # 删除文本中的REPLACE
    text = re.sub(r"REPLACE", "", text)
    text = re.sub(r"```", "", text)
    
    # 移除 Markdown 或其他不必要的符号
    text = re.sub(r"\*\*(.*?)\*\*", r"\\textbf{\1}", text)  # 替换加粗的 Markdown
    # 处理奇怪的符号问题（去除非标准空格、标点等）
    text = re.sub(r"[^\x00-\x7F]+", "", text)  # 移除非 ASCII 字符
    text = re.sub(r"\s+", " ", text)  # 替换多余的空格
    
    return text